package com.xxdh.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.xxdh.domain.dto.NoticeDto;
import com.xxdh.domain.po.Course;
import com.xxdh.domain.po.Notice;
import com.xxdh.domain.po.UserNoticeRelation;
import com.xxdh.domain.vo.NoticeVo;
import com.xxdh.exception.BusiException;
import com.xxdh.mapper.NoticeMapper;
import com.xxdh.service.INoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxdh.service.IUserNoticeRelationService;
import com.xxdh.util.UserHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 公告表 服务实现类
 * </p>
 *
 * @author zwg
 * @since 2024-10-19
 */
@Service
@RequiredArgsConstructor
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {
    private final IUserNoticeRelationService userNoticeRelationService;

    /**
     * 添加公告
     * @param noticeDto 公告信息
     */
    @Transactional
    @Override
    public void addNotice(NoticeDto noticeDto) {
        //获取当前登录用户id
        Long userId = UserHolder.getUserId();
        //将noticeDto转换为Notice对象
        Notice notice = BeanUtil.copyProperties(noticeDto, Notice.class);
        notice.setUserId(userId);
        //保存公告
        save(notice);
        // 保存公告和学生、老师的关系
        userNoticeRelationService.saveNoticeRelationByTeacherIdAndNoticeId(userId, notice.getId());
    }

    /**
     * 更新公告
     * @param noticeDto 公告信息
     */
    @Override
    public void updateNotice(NoticeDto noticeDto) {
        boolean flag = lambdaUpdate().eq(Notice::getId, Long.valueOf(noticeDto.getId()))
                .set(noticeDto.getTitle() != null, Notice::getTitle, noticeDto.getTitle())
                .set(noticeDto.getInfo() != null, Notice::getInfo, noticeDto.getInfo())
                .set(noticeDto.getTime() != null, Notice::getTime, noticeDto.getTime()).update();
        if(!flag){
            throw new BusiException("更新公告失败");
        }
    }

    /**
     * 删除公告
     * @param noticeId 公告id
     */
    @Transactional
    @Override
    public void removeByNoticeId(String noticeId) {
        removeById(noticeId);
        userNoticeRelationService.removeByNoticeId(noticeId);
    }

    /**
     * 根据用户id获取公告列表
     * @param useId 用户id
     * @return
     */
    @Override
    public Map<String, List<NoticeVo>> getNoticeListByUseId(Long useId) {
        //获取公告和用户关系列表
        List<UserNoticeRelation> userNoticeRelations = userNoticeRelationService.getUserNoticeRelationListByUserId(useId);
        if(CollUtil.isEmpty(userNoticeRelations)){
            return new HashMap<>();
        }
        //获取公告列表
        List<NoticeVo> noticeVos = new ArrayList<>();
        for (UserNoticeRelation userNoticeRelation : userNoticeRelations) {
            Notice notice = getById(userNoticeRelation.getNoticeId());
            NoticeVo noticeVo = NoticeVo.builder().id(String.valueOf(notice.getId()))
                    .time(notice.getTime())
                    .title(notice.getTitle())
                    .isRead(userNoticeRelation.getIsRead().toString())
                    .info(notice.getInfo())
                    .userId(String.valueOf(notice.getUserId())).build();
            noticeVos.add(noticeVo);
        }
        //根据isRead进行分组
        Map<String, List<NoticeVo>> collect = noticeVos.stream().collect(Collectors.groupingBy(NoticeVo::getIsRead));
        for(Map.Entry<String, List<NoticeVo>> entry : collect.entrySet()){
            List<NoticeVo> noticeVos1 = entry.getValue();
            //根据时间排序
            if(CollUtil.isNotEmpty(noticeVos1)){
                noticeVos1.sort(((o1, o2)-> o1.getTime().compareTo(o2.getTime())));
            }
        }
        return collect;
    }

    @Override
    public void updateNoticeStatus(String noticeId) {
        Long userId = UserHolder.getUserId();
        userNoticeRelationService.updateNoticeStatusByUserIdAndNoticeId(userId,Long.valueOf(noticeId));
    }
}
